﻿//
//
// 版权所有 (c) 2021-2023 JR  
//
// 特此免费授予获得本软件的任何人以处理本软件的权利，但须遵守以下条件：在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
//
// 软件按“原样”提供，不提供任何形式的明示或暗示的保证，包括但不限于对适销性、适用性和非侵权的保证。
// 在任何情况下，作者或版权持有人均不对任何索赔、损害或其他责任负责，无论是因合同、侵权或其他方式引起的，与软件或其使用或其他交易有关。

using PuppeteerSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EMC.VISITOR.Application;
/// <summary>
/// 需要下载浏览器chromium 浏览器
/// </summary>
public class PuppeteerHelper
{
    public static async void DoScreenshot(string url)
    {
        using var browserFetcher = new BrowserFetcher();
        await browserFetcher.DownloadAsync();
        // ,如果使用browserFetcher.DownloadAsync() 则会自动下载浏览器，不执行上面的代码则需要指定自己手动下载的浏览器地址ExecutablePath
        //await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true,ExecutablePath= "H:\\ProgramDevelop\\chrome-win\\chrome.exe" });
        await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });

        await using var page = await browser.NewPageAsync();
        await page.SetViewportAsync(new ViewPortOptions
        {
            Width = 1920,
            Height = 1080
        });
        await page.GoToAsync(url);
        var picPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.jpg");
        await page.ScreenshotAsync(picPath);
        await browser.CloseAsync();
    }

    public static async void ExportAsPdf(string url)
    {
        using var browserFetcher = new BrowserFetcher();
        await browserFetcher.DownloadAsync();
        await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });
        await using var page = await browser.NewPageAsync();
        await page.GoToAsync(url);
        //等待字体加载完毕
        await page.EvaluateExpressionHandleAsync("document.fonts.ready");
        var pdfPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.pdf");
        await page.PdfAsync(pdfPath);
        await browser.CloseAsync();
    }

    public static async void FetchUrls(string url)
    {
        //浏览器配置
        var options = new LaunchOptions { Headless = true };
        await new BrowserFetcher().DownloadAsync();

        //打开浏览器
        using (var browser = await Puppeteer.LaunchAsync(options))
        using (var page = await browser.NewPageAsync())
        {
            //加载页面
            await page.GoToAsync(url);
            var urlList = new List<string>();
            //获取所有超链接
            var jsSelectAllAnchors = @"Array.from(document.querySelectorAll('a')).map(a => a.href);";
            var urls = await page.EvaluateExpressionAsync<string[]>(jsSelectAllAnchors);
            foreach (string u in urls)
            {
                urlList.Add($"Url: {u}");
            }
            var urlPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "urls.txt");
            File.WriteAllLines(urlPath, urlList);
            await browser.CloseAsync();
        }
    }


    public static async void SearchTest(string url)
    {
        using var browserFetcher = new BrowserFetcher();
        await browserFetcher.DownloadAsync();
        await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });
        await using var page = await browser.NewPageAsync();
        await page.SetViewportAsync(new ViewPortOptions
        {
            Width = 1920,
            Height = 1080,
            //Devtools = true // 启用 Chrome DevTools,无头配置将自动禁用
        });

        //load: window.onload事件被触发时候完成导航,某些情况下它根本不会发生。
        //domcontentloaded: Domcontentloaded事件触发时候认为导航成功
        //networkidle0: 在 500ms 内没有网络连接时就算成功(全部的request结束),才认为导航结束
        //networkidle2: 500ms 内有不超过 2 个网络连接时就算成功(还有两个以下的request),就认为导航完成
        //加载时长 networkidle0 > networkidle2 > load > domcontentloaded 
        //await page.GoToAsync(url, new NavigationOptions() { WaitUntil = new WaitUntilNavigation[] { WaitUntilNavigation.Networkidle0 } });

        // 跟踪日志
        //await page.Tracing.StartAsync(new TracingOptions { Path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"race.json") });
        //await page.Tracing.StopAsync();

        await page.GoToAsync(url);
        await page.WaitForSelectorAsync(".searchbox input");
        await page.FocusAsync(".searchbox input"); // 聚焦
        await page.Keyboard.TypeAsync("CN Tower, Toronto, Ontario, Canada"); // 键盘输入
        await page.ClickAsync(".searchIcon"); // 点击
        await page.WaitForNavigationAsync();
        var content = await page.GetContentAsync();

        // 下载配置
        //var cdp = await page.Target.CreateCDPSessionAsync();
        //await cdp.SendAsync("Page.setDownloadBehavior", new
        //{
        //    behavior = "allow",
        //    downloadPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testing_downloads")
        //});
        //await cdp.DetachAsync();
    }
}
